
#pragma once
#ifndef __DB_H__
#define __DB_H__
#include "SqlRecordSet.h"
#include "SqlDatabase.h"
#include "SqlTable.h"
#include <typeinfo>
#include "SqlValue.h"
#include <string.h>
#include <stdlib.h>

#include "jsoncpp_share.h"

using namespace sql;

class DB
{
private:
    // sql::Database db;
    // const Field *fields;
    // std::string name_db;
    // std::string name_tb;
    // T _m;
public:
    template <typename T>
    static string record2class(Record *pr, T &report)
    {
        const FieldSet *fs = pr->fields();
        const Field *f;
        Json::Value j;
        std::string key;
        for (int i = 0; i < pr->columnCount(); i++)
        {

            f = fs->getByIndex(i);
            key = f->getName();
            Value* val = pr->getValue(i);
            switch (f->getType())
            {
            case type_int:
            case type_time:
                j[key] = (int64_t)val->asInteger();
                break;
            case type_bool:
                j[key] = val->asBool();
                break;
            case type_float:
                j[key] = val->asDouble();
                break;
            case type_text:
                j[key] = val->asString();
                break;
            case type_obj:
            case type_vec:
            default:
                Json::Value jv;
                std::string v = val->asString();
                if (Json::string2json(&jv, v.c_str()))
                {
                    j[key] = jv;
                }
                else
                {
                    std::cout << "DB.h, record2class, can not convert string to Json, Error name: " << key << "value:" << v << std::endl;
                }
                break;
            }
        }

        std::string rs = Json::json2string(j);
        JsonDeserializer jdl(rs);
        jdl.Deserialize(report);
        return rs;
    }

    template <typename T>
    static string class2record(T *cl, Record *record)
    {
        // 1. 将对象转化为json数据
        JsonSerializer jser;
        std::string ss = jser.Serialize(*cl);
        Json::Value j;
        Json::string2json(&j, ss.c_str());
        std::cout << "*cl -> json =" << ss << std::endl;

        // 2.遍历json成员，并对数据正在 建表
        FieldSet fs = FieldSet(cl->field);
        Field *f;
        int i = 0;
        for (auto iter = j.begin(); iter != j.end(); iter++, i++)
        {
            if (iter.key().asString().compare("_ID") == 0) // 每一个表，都会有一个 uniq 的 ID 值
                continue;
            std::string key = iter.key().asString();
            f = fs.getByName(key);
            if (f == NULL)
            {
                // ERROR("无法转换 class->record,class 中没有变量:%s", iter.key().c_str());
                continue;
            }

            switch (f->getType())
            {
            case type_int:
                record->setInteger(key, iter->asInt());
                std::cout << iter.key() << ":" << iter->asInt() << std::endl;
                break;
            case type_time:
                record->setTime(key, sql::time(iter->asUInt64()));
                std::cout << iter.key() << ":" << iter->asUInt64() << std::endl;
                break;
            case type_float:
                record->setDouble(key, iter->asDouble());
                std::cout << iter.key() << ":" << iter->asDouble() << std::endl;
                break;
            case type_bool:
                record->setBool(key, iter->asBool());
                std::cout << iter.key() << ":" << iter->asBool() << std::endl;
                break;
            case type_text:
                record->setString(key, iter->asString());
                std::cout << iter.key() << ":" << iter->asString() << std::endl;
                break;
            case type_vec:
            case type_obj:
            default:
                std::string str = "'" + Json::json2string(j[key]) + "'";
                std::cout << iter.key() << ":" << str << std::endl;
                record->setString(key, str);
                break;
            }
        }
        return ss;
    }

public:
    DB();
    ~DB();
};

#endif // ! __DB_H__
